﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace jvm.classpath
{
    class Classpath
    {
        public Entry bootClasspath;
        public Entry extClasspath;
        public Entry userClasspath;

        public void Parse(string jreOption, string cpOption)
        {
            if (jreOption != null)
            {
                ParseBootAndExtClasspath(jreOption);
            }
            ParseUserClasspath(cpOption);
        }

        void ParseBootAndExtClasspath(string jreOption)
        {
            string jreDir = GetJreDir(jreOption);
            string libPath = Path.Combine(Path.Combine(jreDir, "lib"), "*");
            bootClasspath = new WildcardEntry(libPath);

            string extPath = Path.Combine(Path.Combine(Path.Combine(jreOption, "lib"), "ext"), "*");
            extClasspath = new WildcardEntry(libPath);
        }

        string GetJreDir(string jreOption)
        {
            if (!jreOption.Equals("") && File.Exists(jreOption))
            {
                return jreOption;
            }
            if (File.Exists("./jre"))
            {
                return "./jre";
            }
            string jHome = Environment.GetEnvironmentVariable("JAVA_HOME");
            if (!jHome.Equals(""))
            {
                return Path.Combine(jHome, "jre");
            }
            Console.WriteLine("Can not find jre folder!");
            Environment.Exit(0);

            return "";
        }

        void ParseUserClasspath(string cpOption)
        {
            if (cpOption.Equals(""))
            {
                cpOption = ".";
            }
            userClasspath = EntryFactory.Create(cpOption);
        }

        public Tuple<bool, byte[], Entry> ReadClass(string classname)
        {
            string[] paths = classname.Split('.');
            paths[paths.Length - 1] = paths[paths.Length - 1] + ".class";
            classname = Path.Combine(paths);
            Tuple<bool, byte[], Entry> result = bootClasspath.ReadClass(classname);
            if (result.Item1)
            {
                return result;
            }
            result = extClasspath.ReadClass(classname);
            if (result.Item1)
            {
                return result;
            }
            if (userClasspath != null)
            {
                return userClasspath.ReadClass(classname);
            }
            // 在当前目录下搜索
            return new Tuple<bool, byte[], Entry>(false, null, null);
        }
    }
}
